﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace HMIWebDisplay
{
    public class DisplayReference
    {
        public string DisplayReferenceID { get; private set; }
        public string PointName { get; private set; }
        public string ParameterName { get; private set; }
        public string ReferenceType { get; private set; }
        public DisplayBinding DisplayBinding { get; set; }
        public XElement XElement { get; private set; }

        public static IEnumerable<DisplayReference> ParseXDocument(XDocument xDocument)
        {
            var pointReferences = new List<DisplayReference>();

            foreach (var xElement in xDocument.Descendants("dataobject"))
            {
                pointReferences.AddRange(ParseXElement(xElement));
            }

            return pointReferences;
        }

        public static IEnumerable<DisplayReference> ParseXElement(XElement xElement)
        {

            var pointReferences = new List<DisplayReference>();
            var referenceType = xElement.Attribute("type");
            var referenceID = xElement.Attribute("id");

            if (referenceType != null && referenceID != null)
            {
                if (referenceType.Value == "HMIPage.Generic")
                    pointReferences.Add(new DisplayReference
                        {
                            DisplayReferenceID = referenceID.Value,
                            PointName =
                                xElement.Elements("property").First(
                                    x => CheckAttributeValue(x, "name", "PointRefPointName")).Value,
                            ParameterName =
                                xElement.Elements("property").First(
                                    x => CheckAttributeValue(x, "name", "PointRefParamName")).Value,
                            ReferenceType = referenceID.Value,
                            XElement = xElement
                        });
                else if (referenceType.Value == "HMIPage.ScriptData")
                {
                    var pointList = new List<string>(
                        xElement.Elements("property")
                            .First(x => CheckAttributeValue(x, "name", "CommaDelimitedPointNames"))
                            .Value.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));

                    var parameterList = new List<string>(
                        xElement.Elements("property")
                            .First(x => CheckAttributeValue(x, "name", "CommaDelimitedParameters"))
                            .Value.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));

                    for (int i = 0; i < pointList.Count; i++)
                    {
                        pointReferences.Add(new DisplayReference
                            {
                                DisplayReferenceID = referenceID.Value,
                                PointName = pointList[i],
                                ParameterName = parameterList[i],
                                ReferenceType = referenceType.Value,
                                XElement = xElement
                            });
                    }

                }
            }

            return pointReferences;
        }

        private static bool CheckAttributeValue(XElement xElement, string attributeName, string attributeValue)
        {
            var xAttribute = xElement.Attribute(attributeName);
            return xAttribute != null && xAttribute.Value == attributeValue;
        }

        public override string ToString()
        {
            return PointName + "." + ParameterName;
        }
    }
}
